/**
 * @file users.py
 * @brief User-related API routes for Meeting Management System.
 * @author Ziyi Wang
 *
 * Provides user registration, login, CRUD, and permission control endpoints.
 */
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from typing import List
from datetime import timedelta

from ..database import get_db
from ..models.schemas import User, UserCreate, UserUpdate, Token
from ..models.models import User as UserModel
from ..auth import (
    authenticate_user, 
    create_access_token, 
    get_password_hash, 
    get_current_active_user,
    get_admin_user,
    ACCESS_TOKEN_EXPIRE_MINUTES
)
from fastapi.security import OAuth2PasswordRequestForm

router = APIRouter(
    prefix="/api/users",
    tags=["users"],
    responses={404: {"description": "Not found"}},
)

/**
 * @brief Login endpoint for JWT token (user authentication).
 * @param form_data OAuth2 form data (username, password)
 * @param db Database session
 * @return JWT access token
 * @exception HTTPException 401 if authentication fails
 */
@router.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
    user = authenticate_user(db, form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="用户名或密码不正确",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}

/**
 * @brief Get current user info.
 * @param current_user Current user (from dependency)
 * @return User info
 */
@router.get("/me", response_model=User)
async def read_users_me(current_user: UserModel = Depends(get_current_active_user)):
    return current_user

/**
 * @brief Create a new user (admin only).
 * @param user UserCreate schema
 * @param db Database session
 * @param current_user Current admin user
 * @return Created user
 * @exception HTTPException 400 if username/email exists
 */
@router.post("/", response_model=User, status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate, db: Session = Depends(get_db), current_user: UserModel = Depends(get_admin_user)):
    db_user = db.query(UserModel).filter(UserModel.username == user.username).first()
    if db_user:
        raise HTTPException(status_code=400, detail="用户名已存在")
    
    db_email = db.query(UserModel).filter(UserModel.email == user.email).first()
    if db_email:
        raise HTTPException(status_code=400, detail="邮箱已被使用")
    
    hashed_password = get_password_hash(user.password)
    db_user = UserModel(
        username=user.username,
        email=user.email,
        hashed_password=hashed_password,
        full_name=user.full_name,
    )
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

/**
 * @brief Register a new user (open to all).
 * @param user UserCreate schema
 * @param db Database session
 * @return Created user
 * @exception HTTPException 400 if username/email exists
 */
@router.post("/register", response_model=User, status_code=status.HTTP_201_CREATED)
def register_user(user: UserCreate, db: Session = Depends(get_db)):
    db_user = db.query(UserModel).filter(UserModel.username == user.username).first()
    if db_user:
        raise HTTPException(status_code=400, detail="用户名已存在")
    
    db_email = db.query(UserModel).filter(UserModel.email == user.email).first()
    if db_email:
        raise HTTPException(status_code=400, detail="邮箱已被使用")
    
    hashed_password = get_password_hash(user.password)
    db_user = UserModel(
        username=user.username,
        email=user.email,
        hashed_password=hashed_password,
        full_name=user.full_name,
        is_admin=False,  # 新注册用户不是管理员
    )
    db.add(db_user)
    db.commit()
    db.refresh(db_user)
    return db_user

/**
 * @brief Get all users (admin only).
 * @param skip Offset
 * @param limit Limit
 * @param db Database session
 * @param current_user Current admin user
 * @return List of users
 */
@router.get("/", response_model=List[User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db), current_user: UserModel = Depends(get_admin_user)):
    users = db.query(UserModel).offset(skip).limit(limit).all()
    return users

/**
 * @brief Get a specific user by ID.
 * @param user_id User ID
 * @param db Database session
 * @param current_user Current user
 * @return User info
 * @exception HTTPException 403 if no permission, 404 if not found
 */
@router.get("/{user_id}", response_model=User)
def read_user(user_id: int, db: Session = Depends(get_db), current_user: UserModel = Depends(get_current_active_user)):
    # 管理员可以查看任何用户，普通用户只能查看自己
    if not current_user.is_admin and current_user.id != user_id:
        raise HTTPException(status_code=403, detail="没有权限查看其他用户信息")
    
    db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
    if db_user is None:
        raise HTTPException(status_code=404, detail="用户不存在")
    return db_user

/**
 * @brief Update user info.
 * @param user_id User ID
 * @param user UserUpdate schema
 * @param db Database session
 * @param current_user Current user
 * @return Updated user
 * @exception HTTPException 403 if no permission, 404 if not found
 */
@router.put("/{user_id}", response_model=User)
def update_user(
    user_id: int, 
    user: UserUpdate, 
    db: Session = Depends(get_db), 
    current_user: UserModel = Depends(get_current_active_user)
):
    # 管理员可以更新任何用户，普通用户只能更新自己
    if not current_user.is_admin and current_user.id != user_id:
        raise HTTPException(status_code=403, detail="没有权限修改其他用户信息")
    
    db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
    if db_user is None:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    # 更新字段
    user_data = user.model_dump(exclude_unset=True)
    if "password" in user_data:
        user_data["hashed_password"] = get_password_hash(user_data.pop("password"))
    
    for key, value in user_data.items():
        setattr(db_user, key, value)
    
    db.commit()
    db.refresh(db_user)
    return db_user

/**
 * @brief Delete a user (admin only).
 * @param user_id User ID
 * @param db Database session
 * @param current_user Current admin user
 * @return None
 * @exception HTTPException 404 if not found
 */
@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_user(user_id: int, db: Session = Depends(get_db), current_user: UserModel = Depends(get_admin_user)):
    db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
    if db_user is None:
        raise HTTPException(status_code=404, detail="用户不存在")
    
    db.delete(db_user)
    db.commit()
    return None 